当您在多个分支上并行进行开发时,简单的git checkout将更新您的代码以匹配您喜欢的任何分支。但是不幸的是,如果您要连接的数据库在每个分支上的架构都不同,则断开连接会导致很多问题。
在进行Django开发时,为解决此问题,我为每个分支维护一个唯一的数据库,并设置了一个git挂钩,以确保每次分支切换后我都指向正确的数据库。
详细方法
在我的设置中,settings.py导入了一个未检入git的可选local_settings.py。
如果分支是master,staging或dev,则下面的git hook脚本将更改该文件中的BRANCH设置以匹配您刚切换到的分支。如果没有,它就一个人呆着。 (这里的想法是,您不想为每个一次性分支设置整个数据库,但是您可以-只需从脚本中删除if即可。)
结帐后git hook
将此脚本代码放在.git / hooks / post-checkout文件中,以设置BRANCH变量:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#!/bin/sh # if this is a file checkout – do nothing if [ "$3" == "0" ]; then exit; fi newHEAD=$2 newHEADName=`git symbolic-ref --short HEAD` if [[ "$newHEADName" =~ ^(master|staging|dev)$ ]]; then echo [hooks/post-checkout] Changing BRANCH to $newHEADName: sed -i "s/^BRANCH = .*/BRANCH = '$newHEADName'/" myapp/local_settings.py sed -i "s/^BRANCH = .*/BRANCH = '$newHEADName'/" ventus/local_settings.py else echo [hooks/post-checkout] Did not change DB setting, unknown $newHEADName. fi |
settings.py导入local_settings
在settings.py中,我们像这样加载local_settings.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
DATABASES = {...} ## Read local settings. `get_additional_local_settings` lets you add settings ## in your local_settings that are a function of other settings. I pass ENV, here, ## but if you need other variables, simply add them. Make sure you accept ## **kwargs in your `get_additional_local_settings` in case others change the list. def get_additional_local_settings(**kwargs): return {} try: from .local_settings import * except ImportError: pass additional_local_settings = get_additional_local_settings( BRANCH=BRANCH, DATABASES=DATABASES ) if additional_local_settings: for setting_name, setting_value in additional_local_settings.items(): globals()[setting_name] = setting_value |
local_settings.py使用BRANCH更改数据库
然后,local_settings.py应该包含以下内容:
1 2 3 4 5 6 7 8 9 10 11 12 |
def get_additional_local_settings(BRANCH, DATABASES, **kwargs): db_name = 'mydbname_{}'.format(BRANCH, 'local') for k, obj in DATABASES.items(): obj['NAME'] = db_name return { 'DATABASES': DATABASES, } # BRANCH will be updated by post-checkout git hook. BRANCH = 'master' |